package com.bardpub.controls.flvplayer
{
	import com.bardpub.controls.BComponent;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	import flash.display.StageAlign;
	import flash.display.StageDisplayState;
	import flash.display.StageScaleMode;
	import flash.events.AsyncErrorEvent;
	import flash.events.Event;
	import flash.events.NetStatusEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.geom.Point;
	import flash.media.Video;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	
	public class KPlayer extends BComponent
	{
		
		private var __video:Video;
		private var __stream:NetStream;
		private var __connect:NetConnection;
		private var __bg:Shape;
		private var __client:Object;
		private var __bufferTime:int = 3;
		private var __url:String;							//flv文件地址
		private var __autoPlay:Boolean = true;				//是否自动播放
		private var __videoWidth:Number;
		private var __videoHeight:Number;
		private var __duration:Number;
		private var __running:Boolean = false;				//是否在运行

		private var __loaded:Boolean = false;				//是否在载入数据
		
		private var __control:IKControlBar;
		private var __controlisout:Boolean = false;			//控制条是否在外部
		
		private var __oldScaleMode:String;
		private var __oldStageAlign:String;
		private var __oldwidth:Number;
		private var __oldheight:Number;
		private var __oX:Number;
		private var __oY:Number;
		
		
		public static const RUNNING:String  = "running";
		public static const STOP:String = "stop";
		public static const START:String = "start";
		public static const PAUSE:String = "pause";
		public static const RESUME:String = "resume";
		public static const FULLSCREEN:String = "fullscreen";
		
		
		
		
		
		
		/**
		 * 创建 com.bardpub.controls.flvplayer.KPlayer 类的新实例
		 * @param	parent	父显示对象
		 * @param	x		相对于父显示对象的x坐标
		 * @param	y		相对于父显示对象的y坐标
		 * @param 	source	flv文件地址
		 */
		public function KPlayer(parent:DisplayObjectContainer = null, x:Number = 0, y:Number = 0, source:String = null) 
		{
			super(parent, x, y);
			url = source;
			
		}
		
		/**
		 * 播放FLV
		 * @param	url		flv文件地址
		 */
		public function play(url:String = null):void 
		{
			if (url != null)
			{
				__url = url;
			}
			
			if (__url == null) return;
			dispose();
		
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			
			__loaded = false;
			__stream.play(__url);
			__running = true;
		}
		
		/**
		 * 在全屏/非全屏之间切换
		 */
		public function fullscreen():void 
		{
			if (stage.displayState == null)
			{
				throw new Error("当前播放器设置不允许全屏");
				return;
			}
			if (stage.displayState == StageDisplayState.NORMAL)
			{
				stage.displayState = StageDisplayState.FULL_SCREEN;
				__oldScaleMode = stage.scaleMode;
				__oldStageAlign = stage.align;
				stage.scaleMode = StageScaleMode.NO_SCALE;
				stage.align = StageAlign.TOP_LEFT;
				
			}
			else 
			{
				stage.scaleMode = __oldScaleMode;
				stage.align = __oldStageAlign;
				stage.displayState = StageDisplayState.NORMAL;
			}
			
		}
		
		
		
		
		/**
		 * 暂停播放
		 */
		public function pause():void 
		{
			__running = false;
			__stream.pause();
		}
		
		/**
		 * 恢复播放
		 */
		public function resume():void 
		{
			__running = true;
			__stream.resume();
		}
		
		/**
		 * 在flv文件中搜索到指定百分比的位置，并将播放头设置在此处
		 * @param	percent
		 */
		public function seek(percent:Number):void 
		{
			if (percent == 1) percent = .995;
			__stream.seek(percent * __duration);
		}
		
		/**
		 * 清除占用资源
		 */
		public function dispose():void 
		{
			
			__running = false;
			__video.clear();
			__stream.close();
			__connect.close();
		}
		
		/**
		 * 添加播放控制条
		 * @param	control	控制条对象 接口类型IKcontrolBar
		 * @param	out	控制条是否在播放器外部
		 */
		public function addControlbar(control:IKControlBar, out:Boolean = false):void 
		{
			__control = control;
			__controlisout = out;
			var c:DisplayObject = DisplayObject(__control);
			if (!out)
			{
				addChild (c)
				c.x = 0;
				invalidate();
			}
			c.addEventListener(START, onControlBarStart);
			c.addEventListener(PAUSE, onControlBarPause);
			c.addEventListener(RESUME, onControlBarResume);
			c.addEventListener(FULLSCREEN, onControlBarFullScreen);
		}
		
		
		/**
		 * 重载onAddedToStage方法 给stage添加fulscreen事件侦听
		 * @param	e
		 */
		override protected function onAddedToStage(e:Event):void 
		{
			stage.addEventListener(Event.FULLSCREEN, onFullScreen);
			super.onAddedToStage(e);
		}
		
		
		
		/**
		 * 重载addChildren虚方法，添加KPlayer所需要的子显示对象
		 */
		override protected function addChildren():void 
		{
		
			if (width == 0)
			{
				width = 400;
				height = 170;
			}
			
			__bg = new Shape();
			__bg.graphics.beginFill(0);
			__bg.graphics.drawRect(0, 0, 1, 1);
			__bg.graphics.endFill();
			__bg.width = width;
			__bg.height = height;
			addChild(__bg);
			
			
			__client = new Object();
			__client.onMetaData = onMetaData;
			
			__video = new Video(width, height);
			__video.smoothing = true;
			addChild(__video);
			
			__connect = new NetConnection();
			__connect.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
			__connect.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
			__connect.connect(null);
			
			__stream = new NetStream(__connect);
			__stream.client = __client;
			__stream.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
			__stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
			
			__video.attachNetStream(__stream);
			
			
		}
		
		/**
		 * 重载draw方法
		 */
		override public function draw():void 
		{
			super.draw();
		
			autoSize();
		}
		
		
		
		/**
		 * 自动调整视频大小
		 */
		protected function autoSize():void 
		{
			__bg.width = width;
			__bg.height = height;
			
			
			if (__control != null)
			{
				__control.autoSize(width, height);
			}
		
			if (__videoWidth / __videoHeight >= width / height)
			{
				
				__video.width = width;
				__video.height = __videoHeight * __video.width / __videoWidth;
				__video.y = (height - __video.height) / 2;
				__video.x = 0;
				
			}
			else 
			{
				__video.height = height;
				__video.width = __videoWidth *  __video.height / __videoHeight;
				__video.x = (width - __video.width) / 2;
				__video.y = 0;
			}
		}
		
		/**
		 * 当metadata数据载入时
		 * @param	info
		 */
		private function onMetaData(info:Object):void 
		{
			__videoWidth = info.width
			__videoHeight = info.height;
			__duration = info.duration;
			invalidate();
		}
		
		
		/*===================================================================
		 * handlers
		 ===================================================================*/
		 
		/**
		 * enterFrame
		 * @param	e
		 */
		private function enterFrameHandler(e:Event):void 
		{
			
			if (!__loaded)
			{
				
				if (__control != null)
				{
					__control.loadProgress = __stream.bytesLoaded / __stream.bytesTotal;
				}
				if (__stream.bytesLoaded / __stream.bytesTotal == 1)
				{
					__loaded = true;
				}
			}
			
			if (__running)
			{
				if (__control != null)
				{
					__control.playedTime = __stream.time/__duration;
				}
			}
			
		}
		
		private function onNetStatus(e:NetStatusEvent):void 
		{
			switch (e.info.code) {
                case "NetConnection.Connect.Success":
                    //
                    break;
                case "NetStream.Play.StreamNotFound":
                    trace("Unable to locate video: " + __url);
                    break;
				
				case "NetStream.Play.Start":
					dispatchEvent(new Event(START));	
					break;
				case "NetStream.Play.Stop":
					
					__stream.seek(0);
					__stream.pause();
					__running = false;
					dispatchEvent(new Event(STOP));
					break;
				case "NetStream.Buffer.Full":
				/*
					fullTimer = getTimer();
					bufferSprite.visible = false;
					*/
					break;
				case "NetStream.Buffer.Empty":
					/*
					if (loaded)
						break;
					if (getTimer() - fullTimer < 1 )
						break;
					if (!running) 
						break;
					bufferSprite.visible = true;
					bufferSprite.alpha = 0;
					TweenLite.to(bufferSprite, 1, {alpha:1});
					*/
					break;
            }
		}
		
		private function onSecurityError(e:SecurityErrorEvent):void 
		{
			
		}

		private function onAsyncError(e:AsyncErrorEvent):void 
		{
			
		}
		
		/**
		 * 当播放器在全屏/非全屏状态下切换时发生
		 * @param	e
		 */
		private function onFullScreen(e:Event):void 
		{
			if (stage.displayState == StageDisplayState.FULL_SCREEN)
			{
				__oldwidth = width;
				__oldheight = height;
				width = stage.stageWidth;
				height = stage.stageHeight;
				__oX = x;
				__oY = y;
				var p:Point = this.parent.localToGlobal(new Point(0, 0));
				x = p.x;
				y = p.y;
			}
			else 
			{
				x = __oX;
				y = __oY;
				width = __oldwidth;
				height = __oldheight;
			}
			autoSize();
		}
		
		
		/**
		 * 当控制条发出全屏/非全屏事件时发生
		 * @param	e
		 */
		private function onControlBarFullScreen(e:Event):void 
		{
			fullscreen();
		}
		
		/**
		 * 当控制条发出继续播放事件时发生
		 * @param	e
		 */
		private function onControlBarResume(e:Event):void 
		{
			resume();
		}
		
		/**
		 * 当控制条发出暂停事件时发生
		 * @param	e
		 */
		private function onControlBarPause(e:Event):void 
		{
			pause();
		}
		
		/**
		 * 当控制条发出开始事件时发生
		 * @param	e
		 */
		private function onControlBarStart(e:Event):void 
		{
			play();
		}
		
		
		/*===================================================================
		 * getter/setter
		 ===================================================================*/
		 
		/**
		 * 获取设置flv文件地址
		 */
		public function get url():String { return __url;}
		public function set url(value:String):void 
		{
			__url = value;
			if (__autoPlay) play();
		}
		
		/**
		 * 获取/设置是否自动播放
		 */
		public function get autoPlay():Boolean {return __autoPlay;}
		public function set autoPlay(value:Boolean):void {__autoPlay = value;}
		
		/**
		 * 获取flv的总时间
		 */
		public function get duration():Number {return __duration;}
		
		/**
		 * 获取已播放时间
		 */
		public function get playedTime():Number {return __stream.time;}
		
		/**
		 * 获取播放器是否正在播放
		 */
		public function get running():Boolean {return __running;}
		
		
	}
}